#include "chemnitz_socket.h"

extern const char *SOCKET_PATH;
static const uint32_t LOCALHOST = 0x0100007F;

CHEMNITZ_SOCKET chemnitz_socket_open (void)
{
	int *chemnitz_socket;
	uint16_t port;
	int sockfd;
	int infile;
	int32_t e;
	struct sockaddr_in server_addr;

	// find the port on which chemnitzd is listening
	infile = open (SOCKET_PATH, O_RDONLY);
	if (infile < 0)
	{
		return 0;
	}
	e = (int32_t) read (infile, (void *) &port, sizeof (port));
	if (e != (int32_t) sizeof (port))
	{
		return 0;
	}
	(void) close (infile);

	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = LOCALHOST;
	server_addr.sin_port = htons (port);
	sockfd = socket (AF_INET, SOCK_STREAM, 0);
	e = (int32_t) connect (sockfd, (struct sockaddr *) &server_addr, (socklen_t) sizeof (server_addr));
	if (e == -1)
	{
		(void) close (sockfd);
	}

	chemnitz_socket = (int *) malloc (sizeof (*chemnitz_socket));
	if (! chemnitz_socket)
	{
		return 0;
	}
	*chemnitz_socket = sockfd;
	return chemnitz_socket;
}

bool chemnitz_socket_is_open (CHEMNITZ_SOCKET socket)
{
	if (socket == 0)
	{
		return false;
	}
	else
	{
		return true;
	}
}

size_t chemnitz_socket_read (CHEMNITZ_SOCKET socket, uint8_t *buffer, size_t count)
{
	uint32_t v;
	ssize_t c;
	v = (uint32_t) count;
	v = htonl (v);
	c = write (*socket, &v, sizeof (v));
	c = read (*socket, buffer, count);
	return (size_t) c;
}

void chemnitz_socket_close (CHEMNITZ_SOCKET socket)
{
	uint32_t v = 0;
	ssize_t c;
	if (socket)
	{
		c = write (*socket, &v, sizeof (v));
		(void) close (*socket);
		free (socket);
	}
}

